package servicesImp.expertInfo;


import StaticFinal.CrudType;
import base.IBaseServicesWithoutBLOBsImpl;
import exception.WTException;
import org.apache.commons.lang.StringUtils;
import org.springframework.transaction.annotation.Transactional;
import services.expertInfo.ExpertBaseServices;
import services.expertInfo.IBaseExpertInfoServices;
import services.expertInfo.LeaderCheckServices;
import util.JsonUtil;
import util.ObjUtil;
import wt.entity.expertInfo.BaseExpertInfo;
import wt.entity.expertInfo.ExpertBase;
import wt.entity.expertInfo.LeaderCheckWithBLOBs;

import java.util.List;

/**
 * Created by Administrator on 2017/10/14.
 */

public abstract class BaseExpertInfoServicesImp<Record extends BaseExpertInfo, RecordExample> extends IBaseServicesWithoutBLOBsImpl< Record, RecordExample> implements IBaseExpertInfoServices<Record,RecordExample>{

    public abstract Record getEntity();

    public abstract RecordExample getRecordExample();

    public abstract LeaderCheckServices getLeaderCheckServices();

    public abstract ExpertBaseServices   getExpertBaseServices();

    public void expertUpdateByPrimaryKeySelective(Record record) throws Exception {
        Record temp = getEntity();
        temp.setId(record.getId());
        temp.setCrudType(CrudType.update);
        temp.setCrudData(JsonUtil.obj2Json(record));
        getCurrentProxy().updateByPrimaryKeySelective(temp);
    }

    public void expertInsertSelective(Record record) throws Exception {
        record.setCrudType(CrudType.insert);
        getCurrentProxy().insertSelective(record);
    }

    public void expertDeleteByPrimaryKey(String id) throws Exception {
        Record temp = getEntity();
        temp.setId(id);
        temp.setCrudType(CrudType.delete);
        getCurrentProxy().updateByPrimaryKeySelective(temp);
    }

    public List<Record> expertSelectByExpertId(String expertId) throws Exception {
        RecordExample recordExample = getRecordExample();

        Object criteria = recordExample.getClass().getMethod("createCriteria").invoke(recordExample);
        try {
            criteria.getClass().getMethod("andExpertIdEqualTo",String.class).invoke(criteria, expertId);
        } catch (Exception e) {
            criteria.getClass().getMethod("andIdEqualTo",String.class).invoke(criteria, expertId);
        }

        List<Record> recordList = selectByExample(recordExample);

        for (int i = 0; i < recordList.size(); i++) {
            recordList.set(i, toExpertView(recordList.get(i)));
        }

        return recordList;
    }


    public Record expertSelectByPrimaryKey(String id) throws Exception {
        Record record = selectByPrimaryKey(id);
        record = toExpertView(record);
        return record;
    }

    public int expertCancelApplyByPrimaryKey(String id) throws Exception {
        Record record = selectByPrimaryKey(id);
        if (record.getCrudType() == CrudType.select) {
            return 0;
        } else if (record.getCrudType() == CrudType.insert) {
            return getCurrentProxy().deleteByPrimaryKey(id);
        } else {
            record.setCrudType(CrudType.select);
            record.setCrudData("");
            return getCurrentProxy().updateByPrimaryKey(record);
        }
    }

    private Record toExpertView(Record record) {
        if (record != null && record.getCrudType() == CrudType.update) {
            Record record1 = (Record) JsonUtil.json2Obj(record.getCrudData(), getEntity().getClass());
            ObjUtil.insertSelectiveGETSET(record1, record);
            return record1;
        } else {
            return record;
        }
    }


    @Transactional
    public void adminUpdateByPrimaryKeySelective(Record record) throws Exception {
        Record oldRecord = selectByPrimaryKey(record.getId());
        if (oldRecord.getCrudType() != CrudType.select) {
            throw new WTException(WTException.FOUND_NOT_CHECK_DATA);
        }
        record.setCrudData("");
        getCurrentProxy().updateByPrimaryKeySelective(record);
        ExpertBase expertBase = getExpertBaseServices().selectByPrimaryKey(oldRecord.getExpertId());
        recordProcess(oldRecord);
        recordProcess(record);
        LeaderCheckWithBLOBs blobs = LeaderCheckUtil.verifier1Update(oldRecord, record, getTableName(),expertBase);
        getLeaderCheckServices().insertSelective(blobs);
    }

    @Transactional
    public void adminInsertSelective(Record record) throws Exception {
        record.setCrudType(CrudType.select);
        record.setCrudData("");

        ExpertBase expertBase = getExpertBaseServices().selectByPrimaryKey(record.getExpertId());
        recordProcess(record);
        LeaderCheckWithBLOBs blobs = LeaderCheckUtil.verifier1Insert(record, getTableName(), expertBase);
        getCurrentProxy().insertSelective(record);
        getLeaderCheckServices().insertSelective(blobs);
    }



    @Transactional
    public void adminInsertSelective(List<Record> recordList) throws Exception {
        for (Record record:recordList) {
            record.setCrudData("");
            record.setCrudType(CrudType.select);
            getCurrentProxy().insertSelective(record);
            ExpertBase expertBase = getExpertBaseServices().selectByPrimaryKey(record.getExpertId());
            recordProcess(record);
            LeaderCheckWithBLOBs blobs = LeaderCheckUtil.verifier1Insert(record, getTableName(), expertBase);
            getLeaderCheckServices().insertSelective(blobs);
        }
    }

    @Transactional
    public void adminDeleteByPrimaryKey(String id) throws Exception {
        Record oldRecord = selectByPrimaryKey(id);
        if (oldRecord.getCrudType() != CrudType.select) {
            throw new WTException(WTException.FOUND_NOT_CHECK_DATA);
        }
        getCurrentProxy().deleteByPrimaryKey(id);
        ExpertBase expertBase=getExpertBaseServices().selectByPrimaryKey(oldRecord.getExpertId());
        recordProcess(oldRecord);
        LeaderCheckWithBLOBs blobs = LeaderCheckUtil.verifier1Delete(oldRecord, getTableName(), expertBase);
        getLeaderCheckServices().insertSelective(blobs);

    }


    protected  void recordProcess(Record record) throws Exception{

    }


    public List<Record> adminSelectByExpertId(String expertId) throws Exception {
        RecordExample recordExample = getRecordExample();
        Object criteria = recordExample.getClass().getMethod("createCriteria").invoke(recordExample);
        criteria.getClass().getMethod("andCrudTypeNotEqualTo",Short.class).invoke(criteria, CrudType.insert);
        try {
            criteria.getClass().getMethod("andExpertIdEqualTo",String.class).invoke(criteria, expertId);
        } catch (Exception e) {
            criteria.getClass().getMethod("andIdEqualTo",String.class).invoke(criteria, expertId);
        }
        return selectByExample(recordExample);
    }

    @Transactional
    public void adminCheckApplyByPrimaryKey(String id, boolean result, String reason) throws Exception {
        Record oldRecord = selectByPrimaryKey(id);
        short  crudType = oldRecord.getCrudType();
        String crudData = oldRecord.getCrudData();
        LeaderCheckWithBLOBs blobs;

        ExpertBase expertBase=getExpertBaseServices().selectByPrimaryKey(oldRecord.getExpertId());
        if (result) {
            if (crudType == CrudType.update) {

                Record newRecord = (Record) JsonUtil.json2Obj(crudData, getEntity().getClass());
                newRecord.setCrudType(CrudType.select);
                newRecord.setCrudData("");

                recordProcess(oldRecord);
                recordProcess(newRecord);
                blobs = LeaderCheckUtil.verifier1Update(oldRecord, newRecord, getTableName(), expertBase);

                getCurrentProxy().updateByPrimaryKeySelective(newRecord);
                getLeaderCheckServices().insertSelective(blobs);

            } else if (crudType == CrudType.insert) {
                oldRecord.setCrudType(CrudType.select);
                oldRecord.setCrudData("");

                recordProcess(oldRecord);
                blobs = LeaderCheckUtil.verifier1Insert(oldRecord, getTableName(), expertBase);

                getCurrentProxy().updateByPrimaryKeySelective(oldRecord);
                getLeaderCheckServices().insertSelective(blobs);

            } else if (crudType == CrudType.delete) {
                recordProcess(oldRecord);
                blobs = LeaderCheckUtil.verifier1Delete(oldRecord, getTableName(), expertBase);

                getCurrentProxy().deleteByPrimaryKey(oldRecord.getId());
                getLeaderCheckServices().insertSelective(blobs);

            } else {
                throw new WTException("已被审核");
            }

        } else {


            if (crudType == CrudType.update) {
                oldRecord.setCrudType(CrudType.select);
                oldRecord.setCrudData("");
                Record newRecord = (Record) JsonUtil.json2Obj(crudData, getEntity().getClass());

                recordProcess(oldRecord);
                recordProcess(newRecord);
                blobs = LeaderCheckUtil.verifier1UpdateDisagree(oldRecord, newRecord, getTableName(), expertBase, reason);

                getCurrentProxy().updateByPrimaryKeySelective(oldRecord);
                getLeaderCheckServices().insertSelective(blobs);

            } else if (crudType == CrudType.insert) {

                recordProcess(oldRecord);
                blobs = LeaderCheckUtil.verifier1InsertDisagree(oldRecord, getTableName(), expertBase, reason);
                getCurrentProxy().deleteByPrimaryKey(id);
                getLeaderCheckServices().insertSelective(blobs);

            } else if (crudType == CrudType.delete) {
                oldRecord.setCrudType(CrudType.select);
                oldRecord.setCrudData("");
                recordProcess(oldRecord);
                blobs = LeaderCheckUtil.verifier1DeleteDisagree(oldRecord, getTableName(), expertBase, reason);

                getCurrentProxy().updateByPrimaryKeySelective(oldRecord);
                getLeaderCheckServices().insertSelective(blobs);
            } else {
                throw new WTException("已被审核");
            }
        }
    }



    public boolean isExistUnauditedRecord(String expertId) throws Exception {
        if (StringUtils.isEmpty(expertId)) {
            return false;
        }
        RecordExample recordExample = getRecordExample();
        Object criteria = recordExample.getClass().getMethod("createCriteria").invoke(recordExample);
        criteria.getClass().getMethod("andCrudTypeNotEqualTo",Short.class).invoke(criteria, CrudType.select);
        try {
            criteria.getClass().getMethod("andExpertIdEqualTo",String.class).invoke(criteria, expertId);
        } catch (Exception e) {
            criteria.getClass().getMethod("andIdEqualTo",String.class).invoke(criteria, expertId);
        }
        int count = countByExample(recordExample);
        if (count > 0) {
            return true;
        }
        return false;
    }


}
